<?php

namespace app\common\service;
use app\admin\model\SmsRecordModel;
use app\checkbill\logic\CheckMonthFeeLogic;
use app\systems\model\CommonSystemImportDetailModel;
use app\systems\model\CommonSystemImportModel;
use app\common\library\Excel;
use app\common\library\Upload;
use think\facade\Db;
use app\common\service\AbstractService;
use app\common\service\UploadService;
use app\common\service\CommonSystemImportInfoDetailService;
use app\common\service\CommonSystemImportDetailService;
class CommonSystemImportService extends AbstractService
{
    public $startImportLine = 1;
    public $system_import_model;
    public $system_import_detail_model;
    public $system_import_detail_service;

    const STATUS_INIT = 0;
    const STATUS_PENDING = 1;
    const STATUS_SUCCESS = 2;
    const STATUS_FAIL = 3;
    const STATUS_CANCEL = 4;
    const STATUS_WAITING_READ = 5;
    const STATUS_MAP = [
        self::STATUS_INIT => '初始化',
        self::STATUS_PENDING => '正在运行',
        self::STATUS_SUCCESS => '成功',
        self::STATUS_FAIL => '错误',
        self::STATUS_CANCEL => '取消',
        self::STATUS_WAITING_READ => '等待读取',
    ];

    const TYPE_IMPORT_INCOMPLETE_SKU    = 103;
    const TYPE_IMPORT_INCOMPLETE_TIME   = 104;
    const TYPE_IMPORT_SF_PAGE           = 105;
    const TYPE_IMPORT_QC_PAGE           = 106;
    const TYPE_IMPORT_LIAN_LIAN         = 107;
    const TYPE_IMPORT_MONTH_OLD         = 108;
    const TYPE_IMPORT_MONTH_NEW         = 109;

    const TYPE_MAP = [
        self::TYPE_IMPORT_INCOMPLETE_SKU    => "incomplete_sku匹配捆绑导入",
        self::TYPE_IMPORT_INCOMPLETE_TIME   => "订单下单时间导入",
        self::TYPE_IMPORT_SF_PAGE           => "顺丰账单导入",
        self::TYPE_IMPORT_QC_PAGE           => "全程无忧账单导入",
        self::TYPE_IMPORT_LIAN_LIAN         => "连连账单数据导入",
        self::TYPE_IMPORT_MONTH_OLD         => "月度账单老模版数据导入",
        self::TYPE_IMPORT_MONTH_NEW         => "月度账单新模版数据导入",
    ];

    function __construct()
    {
        $this->system_import_model        = new CommonSystemImportModel();
        $this->system_import_detail_model = new CommonSystemImportDetailModel();
    }




    /**
     * @Notes:获取各个平台的services
     * @author: xx
     * @Date: 2024/3/18
     * @param $platform
     * @return Common_system_import_detail_service
     * is_sub_library是否分库
     */
    public  function get_platform_upc_services()
    {
        return  'CommonSystemImportDetailService';
    }




    /**
     * 导入数据
     * @param $data
     * @param int $limit 导入条数限制
     * @return bool
     * @throws \Exception
     * @author: xx
     * @Date: 2024/3/18
     */
    public function operate_import_data($data,$limit=0)
    {
        list($service, $type, $importType, $is_platform_code_select,$params) = $data;
        $is_platform_code_select = $is_platform_code_select ?? 0;
        if ($type == 'save'){
            # 保存文件
            $file = $params['file']??'';
            $tel  = $params['tel']??'';
            $upload_result    = (new upload($file))->upload(null, $importType);
            if (!$upload_result['full_url']) {
                throw new \Exception($upload_result['error']);
            }

            # 格式校验
            $allow_format = ['xlsx', 'xls', 'csv'];
            $suffix = substr($upload_result['url'], strrpos($upload_result['url'], '.') + 1);
            if (!in_array($suffix, $allow_format)) {
                throw new \Exception('导入格式错误,请导入格式' . implode(',', $allow_format));
            }

            # 解析内容入库做异步
            $upload_result = json_encode($upload_result,JSON_UNESCAPED_UNICODE);
            $class_path    = get_class($service);
            $work_number   = $tel;
            //p('/cron/CommonSystemImportCron/importAsynHandle?upload_result='.$upload_result.'&service='.$class_path.'&importType='.$importType.'&is_platform_code_select='.$is_platform_code_select.'&user='.$work_number);exit();
          run_thread_socket('/cron/CommonSystemImportCron/importAsynHandle?upload_result=' . $upload_result . '&service=' . $class_path . '&importType=' . $importType . '&is_platform_code_select=' . $is_platform_code_select . '&user=' . $work_number);
        }
        return true;
    }



    /**
     * 导入异步处理
     * @param $params
     * @return bool|mixed|null
     * @throws \Exception
     * @author: xx
     * @Date: 2024/3/18
     */
    public function asyn_handle($params)
    {
        try {
            ini_set('memory_limit', -1);
            $upload_result = json_decode($params['upload_result'], true);
            $service_name = $params['service'];
            $service = new $service_name;
            $importType = $params['importType'];
            $is_platform_code_select = $params['is_platform_code_select'];
            $work_number = $params['user'] ?? '';

            if(in_array($upload_result['suffix'],['xlsx','xls'])) {
                $excelData = Excel::getExcelData('.' . '/' . $upload_result['url']);
            }else {
                throw new \Exception('导入格式错误');
            }

            if (empty($excelData)) {
                throw new \Exception('文档中没有有效区域数据');
            }

            if (is_callable([$service, '_before_import'])) {
                call_user_func_array([$service, '_before_import'], [$excelData]);
            }

            return $this->save_import_excel_data($excelData, $upload_result, $importType, $work_number, $service, $is_platform_code_select);
        } catch (\Exception $ex) {
            p($ex->getMessage());
            throw new \Exception('导入格式错误');
        }
        return true;
    }

    /**
     * 保存数据
     * @param $excelData
     * @param $upload_result
     * @param $importType
     * @param $createWorkNum
     * @param $uploadService
     * @param int $is_platform_code_select
     * @return bool
     * @throws \Exception
     * @author: xx
     * @Date: 2024/3/18
     */
    public function save_import_excel_data($excel_data, $upload_result, $importType, $createWorkNum, $uploadService, $is_platform_code_select = 0)
    {

        # created_work_no 字段后面再更新，因为导入文件大时，需要一定的时间才完全导入，这段时间先不让用户看到
        $model = $this->system_import_model;
        $model->import_name = $upload_result['name'];
        $model->import_type = $importType;
        $model->import_status = self::STATUS_INIT;
        $model->upload_file_path = $upload_result['url'];
        $model->created_unix = time();
        $model->platform_code = TIKTOK;
        $res = $model->save();
        if (!$res) {
            throw new \Exception('插入系统导入管理失败');
        }

        $detailData  = [];
        $excelData  = isset($excel_data[0]) ? $excel_data[0]:$excel_data;
        //update 2024-06-07
        if(in_array($importType,[108,109])){
            $first_info = current($excelData);
            $full_url   = $upload_result['full_url']??'';
            (new CheckMonthFeeLogic)->add_template_month($first_info,$full_url,$importType);
        }


        foreach ($excelData as $k=>$row) {
                $filteredArray = array_filter($row);
                if(empty($filteredArray)) {
                  //如果数组全部为空,则从原始数组中移除
                  continue;
                }
                $rowData = call_user_func_array([$uploadService, 'get_excel_row_data'], [$row, $createWorkNum]);
                if(!$rowData) continue;
                $detailData[] = [
                    'import_id' => $model->id,
                    'status' => 0,
                    'error_msg' => ' ',
                    'json_info' => json_encode($rowData, JSON_UNESCAPED_UNICODE)
                ];
            }

        $new_platform_code_info = $new_platform_code_services = '';
        $is_sub_library = 0;
        if (!$detailData) {
            throw new \Exception('子项列为空');
        }
        # 根据平台保存数据,先更新记录
        $model->platform_code = TIKTOK;
        $model->is_sub_library = $is_sub_library;
        $model->created_work_no = $createWorkNum;
        $model->upload_num = count($detailData);
        $model->save();
        $system_import_detail_service = new CommonSystemImportInfoDetailService();
        $detail_res = $system_import_detail_service->operate_detail_data($detailData, $new_platform_code_services, $system_import_detail_service, $is_sub_library,$importType);
        if (!isset($detail_res)) {
            throw new \Exception('插入子项列失败');
        }
        return true;
    }


    /**
     * @Notes:前置导入数据数据转换
     * @Author: TCP
     * @author: xx
     * @Date: 2024/3/18
     * @param $excelData
     * @return array
     */
    function before_import_excel_data($excelData)
    {
        $i = 0;
        $newExcelData = [];
        foreach ($excelData as $k => $row) {
            $i++;
            if ($i <= $this->startImportLine) {
                continue;
            }
            $newExcelData[] = $row;
        }
        return $newExcelData;
    }







    /**
     * @Notes:取消导入
     * @Author: TCP
     * @Date: 2021/3/23
     * @Time: 19:49
     */
    public function cancel_import($params)
    {
        try {
            if (empty($params['ids'])) {
                throw new \Exception('请选择要取消导入的数据');
            }

            //判断是否存在
            $exit = $this->system_import_model->where(['id' => $params['ids']])->select();
            $exit = objectToArray($exit);
            if (empty($exit)) {
                throw new \Exception('请正确选择要取消导入的数据');
            }
            $oexit = $this->system_import_model->where(['id' => $params['ids'], 'import_status' => [self::STATUS_SUCCESS, self::STATUS_FAIL, self::STATUS_CANCEL]])->find();
            $oexit = objectToArray($oexit);
            if (!empty($oexit)) {
                throw new \Exception('只有状态为初始化或正在运行才能进行取消!');
            }


            $updata['cancel_work_no'] = '';
            $updata['cancel_unix']    = time();
            $updata['import_status']  = self::STATUS_CANCEL;
            $res = $this->system_import_model->find($updata, ['id' => $params['ids']]);
            //取消子表数据
            $detail_update_data['status']    = 3;

            foreach ($exit as  $ks => $vs) {
                $detail_update_data['import_id'] = $vs['id'];
                Db::name('common_system_import')->update($detail_update_data);
            }

            if (!$res) {
                throw new \Exception('取消失败');
            }

            return json(DefaultResponse(200, true,'操作成功', null));
        } catch (\Exception $e) {
            return json(DefaultResponse(201, false, $e->getMessage(), null));
        }

        return json(DefaultResponse(200, true,'操作成功', null));
    }



    /**
     * 定时任务跑，修改导入状态
     * @return bool|\end\libraries\abstract_broker\unknown|mixed|null
     * @author:xx
     * @Date: 2024/3/16
     */
    public function update_task_status()
    {
        try {
            $data = $this->system_import_model->whereNotIn("import_status", [self::STATUS_SUCCESS, self::STATUS_FAIL, self::STATUS_CANCEL])->select();
            $data = objectToArray($data);
            if ($data) {
                foreach ($data as $task) {
                    $system_import_detail_service = new CommonSystemImportDetailService();
                    $system_import_detail_service->parentStatusChangeNew($task['id']);
                }
                return json(DefaultResponse(200, true,'操作成功', null));
            } else {
                throw new \Exception('无请求数据');
            }
        } catch (\Exception $e) {
            return json(DefaultResponse(201, false, $e->getMessage(), null));
        }

        return json(DefaultResponse(200, true,'操作成功', null));
    }





    /**
     * @Notes:消费队列
     * @author:xx
     * @Date: 2024/3/26
     * @param $message
     */
    public function consume_center_system_import_queue($message)
    {
        try {
            $platform_code = isset($message['platform_code']) ? $message['platform_code'] : "";
            $system_import_detail_service = (new CommonSystemImportDetailService());
            return $system_import_detail_service->run_import_detail($message['id']);
        } catch (\Throwable $e) {
            return $e->getMessage();
        }
        return true;
    }







}